<?php

namespace app\common\service\stat;

use app\common\facade\auth\Auth;
use app\common\service\auth\AuthAdminService;
use app\model\CouponBrand;
use app\model\CouponExtension;
use app\model\CouponOrder;
use app\model\CouponProductChannel;
use Carbon\Carbon;

class StatService
{
    static $date_type = [
        'year' => '%Y',
        'month' => '%Y-%m',
        'day' => '%Y-%m-%d',
    ];

    const SEARCH_TYPE_CPS = 'cps';
    const SEARCH_TYPE_BRAND = 'brand';
    const SEARCH_TYPE_COUPONP_RODUCT_CHANNEL = 'couponProductChannel';

    static $search_type = [
        'date' => [
            'field' => 'DATE_FORMAT(complete_at,"{{date_format}}") as date2,',
            'field_coupon_order' => 'DATE_FORMAT(order_created_at,"{{date_format}}") as date,',
            'group' => 'date',
            'group_settle' => 'date2',
            'join' => 's.date2 = DATE_FORMAT(order_created_at,"{{date_format}}")',
        ],
        'channel' => [  //根据渠道分类
            'field' => 'cnid,',
            'group' => 'cnid',
            'group_settle' => 'cnid',
            'join' => 's.cnid = c.cnid',
            'with' => ['agentChannel'],
            'field_coupon_order' => 'c.cnid,',
        ],
        'serv_type' => [
            'field' => 'serv_type as serv_type2,',
            'group_settle' => 'serv_type2',
            'group' => 'serv_type',
            'join' => 's.serv_type2 = c.serv_type',
            'with' => ['serviceSub'],
            'field_coupon_order' => 'c.serv_type as serv_type,',
        ],
        'agent' => [
            'field' => 'agent_id,',
            'group' => 'agent_id',
            'group_settle' => 'agent_id',
            'join' => 's.agent_id = c.agent_id',
            'with' => ['agent'],
            'field_coupon_order' => 'c.agent_id,',
        ],
        self::SEARCH_TYPE_BRAND => [
            'field' => 'brand_id,',
            'group' => 'obj_id',
            'group_order' =>'c.brand_id',
            'group_settle' => 'brand_id',
            'join' => 's.brand_id = c.brand_id',
            'with' => ['agent','couponBrand','couponProductChannel'],
            'field_coupon_order' => 'c.brand_id,',
        ],

        self::SEARCH_TYPE_CPS => [
            'field' => 'brand_id,',
            'group' => 'obj_id',
            'group_settle' => 'brand_id',
            'group_order' =>'c.brand_id',
            'join' => 's.brand_id = c.brand_id',
            'with' => ['agent','couponBrand'],
            'field_coupon_order' => 'c.brand_id,',
        ],

        self::SEARCH_TYPE_COUPONP_RODUCT_CHANNEL => [
            'field' => 'product_id,',
            'group' => 'obj_id',
            'group_order' =>'c.product_id',
            'group_settle' => 'product_id',
            'join' => 's.product_id = c.product_id',
            'with' => ['agent','couponProductChannel'],
            'field_coupon_order' => 'c.product_id,',
        ],
    ];


    /**
     * 对账单
     */
    public function statements($params, $report = false)
    {

        $this->init();


        $date_type = $params['date_type'] ?? 'day';
        $search_type = $params['search_type'] ?? 'date';
        $order = $search_type == 'date' ? 'date' : (!empty($params['order']) ? $params['order'] : 'profit');
        $date_format = self::$date_type[$date_type];
        $search_type_obj_arr = self::$search_type[$search_type];

        $field = str_replace('{{date_format}}', $date_format, $search_type_obj_arr['field'] ?? '');
        $field_coupon_order = str_replace('{{date_format}}', $date_format, $search_type_obj_arr['field_coupon_order'] ?? '');

        $group = $search_type_obj_arr['group'] ?? '';
        $group_order = $search_type_obj_arr['group_order'] ?? '';
        $with = $search_type_obj_arr['with'] ?? '';
        $group_settle = $search_type_obj_arr['group_settle'] ?? $group;
        $join = str_replace('{{date_format}}', $date_format, $search_type_obj_arr['join'] ?? '');


        $buildParams = $params;
        $params['order_date_type'] = 'order_created_at';
        $buildParams['order_date_type'] = 'complete_at';

        $from = !empty($params['from']) ? $params['from'] : Auth::from();
        $settle_amount_field = ($from == FROM_APP_ADMIN ? 'platform_profit' : 'profit');

        $buildQuery = CouponOrder::query()
            ->withSearch(CouponOrder::$withSearch, $buildParams)
            ->field($field . 'sum(' . $settle_amount_field . ') as settle_amount , "relation" as relation')
            ->where('agent_settle_status', CouponOrder::C_AGENT_SETTLE_STATUS_SUCCESS);
        if ($report) {
            $join = 's.relation = "relation"';
        } else {
            $buildQuery->group($group_settle);
        }
        $buildQuery = $buildQuery->buildSql();


        //查出所有数据的
        $query = CouponOrder::query()
            ->field($field_coupon_order . 'count(id) as order_num,sum(pay_amount) as pay_amount, sum(case when agent_settle_status != 3 THEN ' . $settle_amount_field . ' else 0 end ) as no_settle , s.settle_amount as already_settle_amount')
            ->alias('c')
            ->withSearch(CouponOrder::$withSearch, $params)
            ->with($with)
            ->when($group_order && !$report,function ($query)use($group_order){
                $query->group($group_order);
            })
            ->join([$buildQuery => 's'], $join, 'left')
            ->estimate(); //预估收益
        if (!empty($params['getQuery'])) {
            return $query;
        }
        //兼容品牌 权益商品 与cps 的统计
        if (method_exists($this,$search_type)){
            $query = $this->$search_type($query,$params);
        }

        $query->group($group)
            ->order($order, 'desc')
            ->order('order_num', 'desc');

        if (!empty($params['page'])) {
            $newCountQuery = clone $query;
            $count = $newCountQuery->count();
            $query->page($params['page']);
        }

        if (!empty($params['list_rows'])) {
            $list_rows = $params['list_rows'] ?? 10;
            $query->limit($list_rows);
        }


        $data = $query->select();

        if (!empty($params['page'])) {
            return [
                'total' => $count,
                'data' => $data,
                'current_page' => $params['page'],
            ];
        }
        return $data;


    }

    /**
     * 我的推广的品牌
     * @param $query
     * @param $params
     */
    public function brand($query,$params){

        $query = $query->buildSql();
        $name = $params['name']??'';
        $query =CouponExtension::query()
            ->field([
                'coupon_extension.obj_id as brand_id',
                'coupon_extension.obj_id as obj_id',
                'stat.profit as profit',
                'stat.order_num as order_num',
                'stat.pay_amount as pay_amount',
                'stat.no_settle as no_settle',
                'stat.already_settle_amount as already_settle_amount',
            ])
            ->when($name,function ($query)use($name){
                //名称搜索
                $ids = CouponBrand::query()
                    ->whereLike('name', '%' . trim($name) . '%')->column('id');

                if ($ids){
                    $query->whereIn('obj_id',$ids);
                }else{
                    $query->where('obj_id',-1);
                }

            })
            ->where('type',CouponExtension::TYPE_BRAND)
//            ->field(['*'])
            ->where('agent_id',Auth::id())
            ->with('couponBrand')
            ->where('channel_id',(new CouponExtension())->getChannelId())
            ->join([$query=>'stat'],'obj_id = stat.brand_id','left');

        return $query;


    }

    /**
     * 我的推广的单品
     * @param $query
     * @param $params
     */
    public function couponProductChannel($query,$params){

        $query = $query->buildSql();
        $name = $params['name']??'';


        $query =CouponExtension::query()
            ->field([
                'coupon_extension.obj_id as obj_id',
                'stat.profit as profit',
                'coupon_extension.obj_id as product_id',
                'stat.order_num as order_num',
                'stat.pay_amount as pay_amount',
                'stat.no_settle as no_settle',
                'stat.already_settle_amount as already_settle_amount',
            ])
            ->when($name,function ($query)use($name){
                //名称搜索
                $ids = CouponProductChannel::query()
                    ->whereLike('name', '%' . trim($name) . '%')->column('product_id');

                if ($ids){
                    $query->whereIn('obj_id',$ids);
                }else{
                    $query->where('obj_id',-1);
                }

            })
            ->where('type',CouponExtension::TYPE_PRODUCT)
            ->where('agent_id',Auth::id())
            ->with('couponProductChannel')
            ->where('channel_id',(new CouponExtension())->getChannelId())
            ->join([$query=>'stat'],'obj_id = stat.product_id','left');


        return $query;


    }

    /**
     * 我的推广CPS
     * @param $query
     * @param $params
     */
    public function cps($query,$params){

        $query = $query->buildSql();

        $name = $params['name']??'';


        $query =CouponExtension::query()
            ->field([
                'coupon_extension.obj_id as brand_id',
                'coupon_extension.obj_id as obj_id',
                'stat.profit as profit',
                'stat.order_num as order_num',
                'stat.pay_amount as pay_amount',
                'stat.no_settle as no_settle',
                'stat.already_settle_amount as already_settle_amount',
            ])
            ->when($name,function ($query)use($name){
                //名称搜索
                $ids = CouponBrand::query()
                    ->whereLike('name', '%' . trim($name) . '%')->column('id');

                if ($ids){
                    $query->whereIn('obj_id',$ids);
                }else{
                    $query->where('obj_id',-1);
                }

            })
            ->where('type',CouponExtension::TYPE_CPS)
//            ->field(['*'])
            ->where('agent_id',Auth::id())
            ->with('couponBrand')
            ->where('channel_id',(new CouponExtension())->getChannelId())
            ->join([$query=>'stat'],'obj_id = stat.brand_id','left');

        return $query;
    }


    /**
     * 统计快 传入时间
     * https://s1.ax1x.com/2022/09/06/v7rD2j.png
     */
    public function estimatedIncomeStat($params, $report = false)
    {

        $params['getQuery'] = true;
//        $params['search_type'] = 'channel';

        $query = $this->statements($params, $report);
        $res = $query->find();

        return $res;

    }


    public function init()
    {

        self::$search_type['agent']['with'] = [
            'agent' => function ($query) {
                $query->withField(['username', 'id', 'company_name', 'status']);
            },
        ];

        self::$search_type['channel']['with'] = [
            'agentChannel' => function ($query) {

            }
        ];


        $auth = Auth::instance();


        foreach (self::$search_type as $key => &$value) {

            if ($auth instanceof AuthAdminService) {

                $value['field_coupon_order'] .= 'sum(profit) as profit,sum(platform_profit) as platform_profit,';

            } else {

                $value['field_coupon_order'] .= 'sum(profit) as profit,';

            }
        }

    }


    /**
     *
     * @param $params
     */
    public function chartData($params)
    {
        $start_at = $params['start_at'] = $params['start_at'] ?? Carbon::now()->subDays(30)->format("Y-m-d");
        $end_at = $params['end_at'] = $params['end_at'] ?? Carbon::now()->format("Y-m-d");

        $dates = [];

        for ($i = 0; $i < 8300; $i++) {
            $date = Carbon::parse($start_at)->addDays($i)->format('Y-m-d');
            $dates[] = $date;
            if ($date >= $end_at) {
                break;
            }
        }

        $dateStat = $this->statements($params) ? $this->statements($params)->toArray() : [];


        $dateKeyValue = [];
        foreach ($dateStat as $value) {
            $dateKeyValue[$value['date']] = $value;
        }


        $res = [];
        $res['all_order_number'] = 0;
        $res['all_transaction_amount'] = 0;
        $res['all_profit_amount'] = 0;
        foreach ($dates as $value) {
            $res['orderNum']['x'][] = Carbon::parse($value)->format("m-d");

            $orders = [
                'value' => !empty($dateKeyValue[$value]) ? $dateKeyValue[$value]['order_num'] : 0,
                'pay_amount' => fen2yuan(!empty($dateKeyValue[$value]) ? $dateKeyValue[$value]['pay_amount'] : 0)
            ];

            $res['orderNum']['y'][] = $orders;

            $res['profit']['x'][] = Carbon::parse($value)->format("m-d");

            $amounts = [
                'value' => fen2yuan(!empty($dateKeyValue[$value]) ? $dateKeyValue[$value][Auth::platform() == PLATFORM_ADMIN ? 'platform_profit' : 'profit'] : 0),
                'pay_amount' => fen2yuan(!empty($dateKeyValue[$value]) ? $dateKeyValue[$value]['pay_amount'] : 0)
            ];
            $res['profit']['y'][] = $amounts;

            $res['all_order_number'] += $orders['value'];//总订单
            $res['all_transaction_amount'] += $orders['pay_amount'];// 总金额
            $res['all_profit_amount'] += $amounts['value'];// 总预估收入
        }

        $res['all_transaction_amount'] = bcmul($res['all_transaction_amount'], 1, 2);
        $res['all_profit_amount'] = bcmul($res['all_profit_amount'], 1, 2);

        return $res;
    }
}